package com.tbl.modules.platform.service.impl.system;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.tbl.common.utils.*;
import com.tbl.modules.platform.dao.system.RoleDAO;
import com.tbl.modules.platform.dao.system.RoleMenuDAO;
import com.tbl.modules.platform.dao.system.UserDAO;
import com.tbl.modules.platform.dao.system.UserMenuDAO;
import com.tbl.modules.platform.entity.system.RoleMenu;
import com.tbl.modules.platform.entity.system.User;
import com.tbl.modules.platform.entity.system.UserModel;
import com.tbl.modules.platform.service.system.UserService;
import com.tbl.modules.platform.util.DeriveExcel;
import com.tbl.modules.wms.dao.baseinfo.FactoryAreaDAO;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户接口实现
 * @author 70486
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDAO, User> implements UserService {

    /**
     * 用户DAO
     */
    @Autowired
    private UserDAO userDAO;
    /**
     * 角色service
     */
    @Autowired
    private RoleDAO roleDAO;
    /**
     * 角色菜单DAO
     */
    @Autowired
    private RoleMenuDAO roleMenuDAO;
    /**
     * 用户菜单DAO
     */
    @Autowired
    private UserMenuDAO userMenuDAO;
    /**
     * 厂区DAO
     */
    @Autowired
    private FactoryAreaDAO factoryAreaDAO;


    /**
     * 用户管理获取分页列表
     * @param params 条件
     * @return PageUtils
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page page = new Page(Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("limit").toString()),
                params.get("sidx").toString(), "asc".equalsIgnoreCase(params.get("order").toString()));
        return new PageUtils(page.setRecords(userDAO.selectUserList(page, params)));
    }

    /**
     * 根据登录名获取实体
     * @param username
     * @return User
     */
    @Override
    public User findByUsername(String username) {
        User user = null;
        Map<String, Object> map = new HashMap<>(1);
        map.put("username", username);
        List<User> lstUser = baseMapper.selectByMap(map);
        if (lstUser != null && lstUser.size() > 0){
            user = lstUser.get(0);
        }
        return user;
    }

    /**
     * 判断登录用户属于哪个用户
     * @param username
     * @return Integer
     */
    @Override
    public Integer getByUserName(String username) {
        return userDAO.getByUserName(username);
    }

    /**
     * 登录判断
     * @param username
     * @param pwd
     * @return User
     */
    @Override
    public User getUserByNameAndPwd(String username, String pwd) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("username", username);
        map.put("pwd", pwd);
        return userDAO.getUserByNameAndPwd(map);
    }

    /**
     * 更新登录时间
     * @param pd
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateLastLogin(PageData pd) {
        User user = this.selectById(pd.getLong("USER_ID"));
        if (user != null && !StringUtils.isEmpty(pd.getString("LAST_LOGIN"))){
            user.setLastLogin(Objects.requireNonNull(DateUtils.stringToDate(pd.getString("LAST_LOGIN"), "yyyy-MM-dd HH:mm:ss")).getTime());
        }
        this.updateById(user);
    }

    /**
     * 通过id获取数据
     * @param USER_ID
     * @return User
     */
    @Override
    public User getUserAndRoleById(long USER_ID) {
        User user = baseMapper.selectById(USER_ID);
        if (user != null){
            user.setRole(roleDAO.selectById(user.getRoleId()));
        }
        return user;
    }

    /**
     * 根据用户姓名查询用户
     * @param username
     * @return User
     */
    @Override
    public User getUserAndRoleByIds(String username) {
        User user = userDAO.getUserAndRoleByIds(username);
        if (user != null){
            user.setRole(roleDAO.selectById(user.getRoleId()));
        }
        return user;
    }

    /**
     * 验证当前用户是否具有RFID数据权限
     * @param id
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean getDataManage(Long id) {
        List<RoleMenu> lstRoleMenu = roleMenuDAO.getDataManage(id);
        return lstRoleMenu.size() != 0;
    }

    /**
     * 检查当前用户是否有设备管理权限
     * @param id
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean getDeviceT(Long id) {
        List<RoleMenu> lstRoleMenu = roleMenuDAO.getDeviceT(id);
        return lstRoleMenu.size() != 0;
    }

    /**
     * 获取用户菜单
     * @param id
     * @param type
     * @return Map<String, Object>
     */
    @Override
    public List<Map<String, Object>> getUserMenu(Long id, String type) {
        Map<String, Object> map = new HashMap<>(3);
        map.put("user_id", id);
        map.put("type", Long.valueOf(type));
        User user = userDAO.selectById(id);
        map.put("roleId", user.getRoleId());
        List<Map<String, Object>> valueMap = userMenuDAO.getUserMenu(map);
        List<Map<String, Object>> newList = new ArrayList<>();
        valueMap.forEach(a -> {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("order", a.get("ORDER"));
            map1.put("isquick", a.get("ISQUICK"));
            map1.put("user_id", a.get("USER_ID"));
            map1.put("menu_id", a.get("MENU_ID"));
            map1.put("type", a.get("TYPE"));
            newList.add(map1);
        });
        return newList;
    }

    /**
     * 获取用户菜单
     * @param id
     * @param type
     * @return Map<String, Object>
     */
    @Override
    public List<Map<String, Object>> getUserMenu11(Long id, String type) {
        Map<String, Object> map = new HashMap<>();
        map.put("user_id", id);
        map.put("type", Long.valueOf(type));
        User user = userDAO.selectById(id);
        map.put("roleId", user.getRoleId());
        List<Map<String, Object>> valueMap = userMenuDAO.getUserMenu11(map);
        List<Map<String, Object>> newList = new ArrayList<>();
        valueMap.forEach(a -> {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("order", a.get("ORDER"));
            map1.put("isquick", a.get("ISQUICK"));
            map1.put("user_id", a.get("USER_ID"));
            map1.put("menu_id", a.get("MENU_ID"));
            map1.put("type", a.get("TYPE"));
            newList.add(map1);
        });
        return newList;
    }

    /**
     * 设置用户菜单
     * @param menus
     * @param userid
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean setUserMenu(String menus, Long userid) {
        Map<String, Object> map = new HashMap<>();
        map.put("user_id", userid);
        map.put("type", 0L);
        boolean b = userMenuDAO.deleteUserMenu(map);
        if (b) {
            String[] list = menus.split(",");
            Map<String, Object> userMenuMap;
            for (int i = 0; i < list.length; i++) {
                userMenuMap = new HashMap<>();
                userMenuMap.put("userId", userid);
                userMenuMap.put("menuId", Long.valueOf(list[i]));
                userMenuMap.put("order", (long) (i + 1));
                userMenuMap.put("type", 0L);
                userMenuMap.put("isQuick", null);

                userMenuDAO.insertUserMenus(userMenuMap);
            }
        }
        return b;
    }

    /**
     * 设置用户菜单
     * @param menus
     * @param userid
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean setUserMenus(String menus, Long userid) {
        Map<String, Object> map = new HashMap<>();
        map.put("user_id", userid);
        map.put("type", 1L);
        boolean b = userMenuDAO.deleteUserMenu(map);
        if (b) {
            String[] list = menus.split(",");
            Map<String, Object> userMenuMap ;
            for (int i = 0; i < list.length; i++) {
                userMenuMap = new HashMap<>();
                userMenuMap.put("userId", userid);
                userMenuMap.put("menuId", Long.valueOf(list[i]));
                userMenuMap.put("order", (long) (i + 1));
                userMenuMap.put("type", 1L);
                userMenuMap.put("isQuick", null);

                userMenuDAO.insertUserMenus(userMenuMap);
            }

        }
        return b;
    }

    /**
     * setUserQuickMenu
     * @param menus
     * @param userid
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean setUserQuickMenu(String menus, Long userid) {
        String[] list = menus.split(",");
        Map<String, Object> userMenuMap ;
        for (int i = 0; i < list.length; i++) {
            userMenuMap = new HashMap<>();
            userMenuMap.put("userId", userid);
            userMenuMap.put("menuId", Long.valueOf(list[i]));
            userMenuMap.put("order", (long) (i + 1));
            userMenuMap.put("type", 0L);
            userMenuMap.put("isQuick", 1L);

            userMenuDAO.insertUserMenus(userMenuMap);
        }
        return true;
    }

    /**
     * 设置快捷菜单s
     * @param menus
     * @param userid
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean setUserQuickMenus(String menus, Long userid) {
        Map<String, Object> umMap = new HashMap<>();
        umMap.put("user_id", userid);
        umMap.put("type", 1L);
        umMap.put("isQuick", 1L);

        boolean b = userMenuDAO.deleteUserMenu(umMap);
        if (b) {
            String[] list = menus.split(",");
            Map<String, Object> userMenuMap ;
            for (int i = 0; i < list.length; i++) {
                userMenuMap = new HashMap<>(5);
                userMenuMap.put("userId", userid);
                userMenuMap.put("menuId", Long.valueOf(list[i]));
                userMenuMap.put("order", (long) (i + 1));
                userMenuMap.put("type", 1L);
                userMenuMap.put("isQuick", 1L);

                userMenuDAO.insertUserMenus(userMenuMap);
            }
        }
        return b;
    }


    /**
     * 保存/更新用户
     * @param user
     * @param userFactoryIds
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveU(User user, String userFactoryIds) {
        boolean ret;
        if(StringUtils.isNotBlank(user.getUserFactoryWarehouseIds())){
            String userFactoryWarehouseIds = user.getUserFactoryWarehouseIds().replaceAll("M","");
            //根据用户所属厂区仓库id，获取用户仓库权限实体（二期）
            List<Map<String,Object>> userWarehouseMap = userDAO.findUserWarehouseById(Arrays.stream(userFactoryWarehouseIds.split(","))
                    .map(Long::parseLong).collect(Collectors.toList()));
            //根据用户所属厂区仓库id，获取用户厂区权限实体（一期）
            List<Map<String,Object>> userFactoryMap = userDAO.findUserFactoryById(Arrays.stream(userFactoryWarehouseIds.split(","))
                    .map(Long::parseLong).collect(Collectors.toList()));

            //如果有仓库的ID，那就是默认二期用户，插入二期用户的所属仓库id
            if (userWarehouseMap!=null && userWarehouseMap.size()>0) {
                StringBuilder warehouseStringBuilder = new StringBuilder();
                userWarehouseMap.forEach(map -> warehouseStringBuilder.append(map.get("WAREHOUSE_ID")).append(","));
                user.setUserWarehouseIds(warehouseStringBuilder.substring(0, warehouseStringBuilder.length() - 1));
                //把厂区的清空
                user.setFactoryCode(null);
                user.setUserFactoryIds(null);
            }else {
                //没有仓库的话那就是只有厂区，就是一期的账号，插入一期用户的所属厂区id及厂区编码
                if (userFactoryMap!=null && userFactoryMap.size()>0){
                    StringBuilder factoryStringBuilder = new StringBuilder();
                    StringBuilder factoryCodeStringBuilder = new StringBuilder();
                    userFactoryMap.forEach(map->{
                        factoryStringBuilder.append(map.get("FACTORY_ID")).append(",");
                        factoryCodeStringBuilder.append(factoryAreaDAO.selectById(Long.valueOf((String) map.get("FACTORY_ID"))).getCode()).append(",");
                    });
                    user.setFactoryCode(factoryCodeStringBuilder.substring(0,factoryCodeStringBuilder.length()-1));
                    user.setUserFactoryIds(factoryStringBuilder.substring(0,factoryStringBuilder.length()-1));
                    //把仓库的清空
                    user.setUserWarehouseIds(null);
                }
            }
        }

        //添加
        if (user.getUserId() == null) {
            /*ret = this.insert(user);*/
            ret = userDAO.insertByUser(user);
        }
        //修改
        else {
            /*ret = this.updateById(user);*/
            ret = userDAO.updateByUser(user,userFactoryIds);
        }
        return ret;
    }

    /**
     * 根据主键查询用户
     * @param userId
     * @return User
     */
    @Override
    public User findByUserId(String userId) {
        return userDAO.findByUserId(Long.valueOf(userId));
    }

    /**
     * 根据用户主键修改用户密码
     * @param userId
     * @param columnName
     * @param columnValue
     * @return boolean
     */
    @Override
    public boolean updateUserColumn(long userId, String columnName, String columnValue) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("columnValue", columnValue);
        return userDAO.updateUserColumn(map);
    }

    /**
     * 通过loginname获取数据
     * @param pd
     * @return User
     */
    @Override
    public User findByUId(PageData pd) {
        return userDAO.findbyuid(pd);
    }

    /**
     * 根据用户主键获取用户名称
     * @param ids 多个用户主键
     * @return String
     */
    @Override
    public String getUserNameByIds(String ids) {
        StringBuilder username = new StringBuilder();
        List<User> lstUser = this.selectBatchIds(Arrays.stream(ids.replaceAll("'", "").split(","))
                .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()));
        for (User user : lstUser) {
            username.append(user.getUsername()).append(", ");
        }
        if (!StringUtils.isEmpty(username.toString())){
            username = new StringBuilder(username.substring(0, username.length() - 1));
        }
        return username.toString();
    }

    /**
     * 更改制定用户状态
     * @param state 用户状态1：启用，2：停用
     * @param ids   用户ID，多个以逗号隔开
     * @return boolean
     */
    @Override
    public boolean changeState(String state, String ids) {
        List<User> lstUser = this.selectBatchIds(Arrays.stream(ids.replaceAll("'", "").split(","))
                .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList()));
        for (User user : lstUser) {
            user.setStatus(Long.valueOf(state));
        }
        return this.updateBatchById(lstUser);
    }

    /**
     * 获取导出列
     * @param ids
     * @return List<User>
     */
    @Override
    public List<UserModel> getAllLists(String ids) {
        List<UserModel> list = userDAO.getAllLists(StringUtils.stringToList(ids));
        list.forEach(a -> {
            if (!StringUtils.isEmptyString(a.getLastLogin())){
                a.setLastLogin(DateUtils.longToStringParams(Long.parseLong(a.getLastLogin()), "yyyy-MM-dd HH:mm"));
            }
        });
        return list;
    }

    /**
     * 导出excel
     * @param response
     * @param path
     * @param list
     */
    @Override
    public void toExcel(HttpServletResponse response, String path, List<UserModel> list) {
        try {
            String sheetName = "用户管理表" + "(" + DateUtils.getDay() + ")";
            if (path != null && !"".equals(path)) {
                sheetName = sheetName + ".xls";
            } else {
                response.setHeader("Content-Type", "application/force-download");
                response.setHeader("Content-Type", "application/vnd.ms-excel");
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Expires", "0");
                response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
                response.setHeader("Pragma", "public");
                response.setHeader("Content-disposition", "attachment;filename=" + new String(sheetName.getBytes("gbk"),
                        "ISO8859-1") + ".xls");
            }
            for (UserModel in : list) {
                if (in.getStatus().equals(1L)) {
                    in.setStateName("启用");
                } else if (in.getStatus().equals(2L)) {
                    in.setStateName("禁用");
                } else {
                    in.setStateName("未知");
                }
            }
            Map<String, String> mapFields = new LinkedHashMap<>();
            mapFields.put("username", "用户名");
            mapFields.put("name", "姓名");
            mapFields.put("roleName", "所属角色");
            mapFields.put("deptName", "所属部门");
            mapFields.put("StateName", "状态");
            mapFields.put("email", "邮箱");
            mapFields.put("phone", "手机号码");
            mapFields.put("lastLogin", "最近登录时间");
            mapFields.put("ip", "上次登录IP");
            mapFields.put("remark", "备注");
            DeriveExcel.exportExcel(sheetName, list, mapFields, response, path);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据用户信息获取用户能访问的菜单权限：这里指定一个设备检测的菜单
     * @param user
     * @return int
     */
    @Override
    public int getJcMenuByUser(User user) {
        return userDAO.getJcMenuByUserId(user.getUserId());
    }

    /**
     * 获取所有用户列表:供下拉框使用
     * @param  map
     * @return PageUtils
     */
    @Override
    public PageUtils getUserPageList(Map<String, Object> map) {
        String deptId = (String) map.get("deptId");
        if (StringUtils.isNotEmpty(deptId)) {
            map.put("deptId", Long.valueOf(deptId));
        }
        Page<User> page = this.selectPage(new Query<User>(map).getPage(), new EntityWrapper<>());
        return new PageUtils(page.setRecords(userDAO.getUserPageList(page, map)));
    }

    /**
     * 获取用户下拉列表（台套化配置页面使用）
     * @param page
     * @param queryString
     * @return page
     */
    @Override
    public Page<Map<String, Object>> getUserSelect(PageTbl page, String queryString) {
        Page<Map<String, Object>> pages = new Page<>(page.getPageno(), page.getPagesize());
        Map<String, Object> map = new HashMap<>();
        map.put("queryString", queryString);
        return pages.setRecords(userDAO.getUserQuerySelect(pages, map));
    }

    /**
     * 根据用户信息获取用户能访问的菜单权限：这里指定一个设备检测的菜单
     * @param  map
     * @return List<Map<String,Object>>
     */
    @Override
    public List<Map<String, Object>> getLstMapUser(Map<String, Object> map) {
        Page<User> page = this.selectPage(new Query<User>(map).getPage(), new EntityWrapper<>());
        List<Map<String, Object>> lstMap = new ArrayList<>();
        Map<String, Object> userMap ;
        List<User> lstUser = userDAO.getUserPageList(page, map);
        for (User user : lstUser) {
            userMap = new HashMap<>(2);
            userMap.put("id", user.getUserId());
            userMap.put("text", user.getText());
            lstMap.add(userMap);
        }

        return lstMap;
    }

    /**
     * 获取用户列表（盘点计划添加页面“分配”下拉框使用）
     * @param params
     * @return Page<User>
     */
    @Override
    public Page<User> getSelectUserList(Map<String, Object> params) {
        String queryString = (String) params.get("queryString");
        Page<User> page = this.selectPage(new Query<User>(params).getPage(), new EntityWrapper<User>()
                .like(StringUtils.isNotEmpty(queryString), "username", queryString)
                .or().like(StringUtils.isNotEmpty(queryString), "name", queryString)
        );

        for (User user : page.getRecords()) {
            user.setText(user.getName() + "(" + user.getUsername() + ")");
        }

        return page;
    }

    /**
     * 获取系统中的人(质检收货添加页面使用)
     * @return List<User>
     */
    @Override
    public List<User> getQualityUser() {
        List<User> lstUser = userDAO.selectByMap(new HashMap<>(1));
        for (User user : lstUser) {
            user.setName(user.getName() + "(" + user.getUsername() + ")");
        }
        return lstUser;
    }

    /**
     * @param role_id
     * @return Map<String, Integer>
     */
    @Override
    public Map<String, Integer> getDeviceOrDataAutor(Long role_id) {
        return new HashMap<>(1);
    }

    /**
     * 获取未完成的入库单的数量
     * @return Integer
     */
    @Override
    public Integer getInAmount() {
        return userDAO.getInAmount();
    }

    /**
     * 获取未完成的出库单的数量
     * @return Integer
     */
    @Override
    public Integer getOutAmount() {
        return userDAO.getOutAmount();
    }

    /**
     * 获取异常的数量
     * @return Integer
     */
    @Override
    public Integer getAbnormalAmount() {
        return userDAO.getAbnormalAmount();
    }

    /**
     * 根据用户主键获取用户所属厂、仓库的权限
     * @param userId 用户主键
     * @param usertype 1成品；2原材料
     * @return List<Map>
     */
    @Override
    public List<Map<String, Object>> getUserRoleByUserId(@Param("userId") Long userId, @Param("usertype") Integer usertype){
        User user = userDAO.selectById(userId);
        //查询所有的不应该勾选出来的
        return userDAO.getUserRoleByUserId(usertype,user.getRoleId(),StringUtils.isNotBlank(user.getUserFactoryIds()) ?
                Arrays.stream(user.getUserFactoryIds().split(",")).map(Long::parseLong).collect(Collectors.toList()) : null,
                StringUtils.isNotBlank(user.getUserWarehouseIds()) ?
                Arrays.stream(user.getUserWarehouseIds().split(",")).map(Long::parseLong).collect(Collectors.toList()) : null);
    }

    /**
     * 根据用户主键获取用户所属厂、仓库的权限
     * @param usertype 1成品用户；2原材料用户
     * @return List<Map>
     */
    @Override
    public List<Map<String, Object>> getUserRoleByUserIdTwo(Integer usertype){
        return userDAO.getUserRoleByUserIdTwo(usertype);
    }
}
